﻿# ============================================================
# Windows 批量应用启动管理器（支持启动参数版）
# ============================================================

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$ConfigPath = ".\config.ini"

if (!(Test-Path $ConfigPath)) {
    Write-Host "配置文件 config.ini 不存在！" -ForegroundColor Red
    exit
}

# ------------------INI 读取函数（支持复杂行）-------------------------
function Get-IniValue {
    param($Section, $Key)
    $content = Get-Content $ConfigPath
    $inSection = $false
    foreach ($line in $content) {
        $trim = $line.Trim()
        if ($trim -match "^\[$Section\]") { $inSection = $true; continue }
        if ($trim -match "^\[.+\]") { $inSection = $false; continue }
        if ($inSection -and $trim -like "$Key=*") {
            return $trim.Substring($Key.Length + 1)
        }
    }
    return $null
}

# ------------------读取配置-------------------------
$SmartDelay       = (Get-IniValue "Settings" "SmartDelay") -eq "true"
$BaseDelay        = [int](Get-IniValue "Settings" "BaseDelay")
$RetryCount       = [int](Get-IniValue "Settings" "RetryCount")
$SkipIfRunning    = (Get-IniValue "Settings" "SkipIfRunning") -eq "true"
$CheckCpuIdle     = (Get-IniValue "Settings" "CheckCpuIdle") -eq "true"
$CpuIdleThreshold = [int](Get-IniValue "Settings" "CpuIdleThreshold")
$CpuIdleCheckTimes= [int](Get-IniValue "Settings" "CpuIdleCheckTimes")
$EnableLog        = (Get-IniValue "Settings" "Log") -eq "true"

if ($BaseDelay -eq 0) { $BaseDelay = 1 }
if ($CpuIdleThreshold -eq 0) { $CpuIdleThreshold = 10 }
if ($CpuIdleCheckTimes -eq 0) { $CpuIdleCheckTimes = 3 }

# ------------------日志-------------------------
$LogPath = ".\logs"
if ($EnableLog -and !(Test-Path $LogPath)) { New-Item $LogPath -ItemType Directory | Out-Null }
$LogFile = "$LogPath\Run_$(Get-Date -Format yyyyMMdd).txt"

function Log {
    param($msg)
    $time = (Get-Date).ToString("HH:mm:ss")
    $line = "[$time] $msg"
    Write-Host $line
    if ($EnableLog) { Add-Content -Path $LogFile -Value $line -Encoding UTF8 }
}

# ------------------CPU Idle -------------------------
function Wait-ForCpuIdle {
    param($Process)
    if (-not $CheckCpuIdle) { return }

    Log "等待 CPU 稳定..."

    for ($i = 1; $i -le $CpuIdleCheckTimes; $i++) {
        Start-Sleep -Seconds 1

        $p1 = Get-Process -Id $Process.Id -ErrorAction SilentlyContinue
        if (!$p1) { return }

        $cpu1 = $p1.CPU
        Start-Sleep -Milliseconds 700

        $p2 = Get-Process -Id $Process.Id -ErrorAction SilentlyContinue
        if (!$p2) { return }

        $cpu2 = $p2.CPU

        $delta = ($cpu2 - $cpu1) * 100
        if ($delta -lt $CpuIdleThreshold) {
            Log "CPU 已稳定（增幅 $([int]$delta)%）"
            return
        }

        Log "CPU 仍较高（增幅 $([int]$delta)%），继续检测..."
    }
}

# ------------------智能延迟-------------------------
function Smart-Delay {
    param($Exe)

    $delay = $BaseDelay
    $size = (Get-Item $Exe).Length

    if ($size -gt 100MB) { $delay += 2 }
    if ($Exe -match "Adobe|Steam|Office") { $delay += 1 }

    Log "智能延迟：$delay 秒"
    Start-Sleep -Seconds $delay
}

# ------------------解析启动行（支持参数）-------------------------
function Parse-AppLine {
    param($rawValue)

    if ($rawValue -match "\|") {
        $parts = $rawValue.Split("|", 2)
        return @{ exe = $parts[0].Trim(); args = $parts[1].Trim() }
    }
    return @{ exe = $rawValue.Trim(); args = "" }
}

# ------------------启动应用-------------------------
function Start-App {
    param($Name, $Raw)

    $parsed = Parse-AppLine $Raw
    $ExePath = $parsed.exe
    $Arguments = $parsed.args

    if (!(Test-Path $ExePath)) {
        Log "❌ 未找到文件：$ExePath"
        return
    }

    $procName = [System.IO.Path]::GetFileNameWithoutExtension($ExePath)
    if ($SkipIfRunning -and (Get-Process -Name $procName -ErrorAction SilentlyContinue)) {
        Log "⏭ 已运行，跳过：$Name"
        return
    }

    for ($i = 0; $i -le $RetryCount; $i++) {
        try {
            Log "🚀 启动：$Name"
            if ($Arguments -ne "") {
                $p = Start-Process -FilePath $ExePath -ArgumentList $Arguments -PassThru -ErrorAction Stop
            } else {
                $p = Start-Process -FilePath $ExePath -PassThru -ErrorAction Stop
            }

            Wait-ForCpuIdle $p
            if ($SmartDelay) { Smart-Delay $ExePath } else { Start-Sleep -Seconds $BaseDelay }

            Log "✔ 启动成功：$Name"
            return
        }
        catch {
            Log "❌ 启动失败：$Name（重试 $i / $RetryCount）"
            Start-Sleep -Seconds 1
        }
    }

    Log "⛔ 放弃启动：$Name"
}

# ------------------读取 Apps 并启动-------------------------
$content = Get-Content $ConfigPath
$start = $false

foreach ($line in $content) {
    if ($line -match "^\[Apps\]") { $start = $true; continue }
    if ($start -and $line -match "^\[") { break }
    if ($start -and $line -match "=") {
        $k, $v = $line.Split("=", 2)
        Start-App $k.Trim() $v.Trim()
    }
}

Log "🎉 所有程序已处理完毕。"
